package com.babai.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class FileUtil {

    private static final Log logger = LogFactory.getLog(FileUtil.class);

    public static void download(HttpServletResponse response, String fileName, File targetFile) {
        try {
            //设置输出流
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/octet;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);

            //读取文件
            BufferedInputStream bufferIn = new BufferedInputStream(new FileInputStream(targetFile));
            BufferedOutputStream bufferOut = new BufferedOutputStream(response.getOutputStream());
            byte[] b = new byte[4096];
            int k = 0;
            while ((k = bufferIn.read(b)) != -1) {
                bufferOut.write(b, 0, k);
            }
            bufferOut.flush();
            bufferOut.close();
            bufferIn.close();
        } catch (FileNotFoundException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }

    public static void download(HttpServletResponse response, String fileDir, String fileName) {
        String filePath = fileDir + "/" + fileName;
        try {
            //设置输出流
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setContentType("application/octet;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);

            //读取文件
            File file = new File(filePath);
            BufferedInputStream bufferIn = new BufferedInputStream(new FileInputStream(file));
            BufferedOutputStream bufferOut = new BufferedOutputStream(response.getOutputStream());
            byte[] b = new byte[4096];
            int k = 0;
            while ((k = bufferIn.read(b)) != -1) {
                bufferOut.write(b, 0, k);
            }
            bufferOut.flush();
            bufferOut.close();
            bufferIn.close();
        } catch (FileNotFoundException e) {
            logger.error(e.getMessage(), e);
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }

    public static void toZip(List<File> fileList, String zipPath) throws IOException {
        if (null != fileList && !fileList.isEmpty()) {
            byte[] buf = new byte[1024];
            FileOutputStream os = new FileOutputStream(zipPath);
            ZipOutputStream zipOut = new ZipOutputStream(os);
            for (File file : fileList) {
                FileInputStream in = new FileInputStream(file);
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                int len;
                while ((len = in.read(buf)) > 0) {
                    zipOut.write(buf, 0, len);
                }
                zipOut.closeEntry();
                in.close();
                file.delete();// 清除临时文档
            }
            zipOut.close();
        }
    }

    public static void toZip(List<File> fileList, OutputStream output) throws IOException {
        if (null != fileList && !fileList.isEmpty()) {
            byte[] buf = new byte[1024];
            ZipOutputStream zipOut = new ZipOutputStream(output);
            for (File file : fileList) {
                FileInputStream in = new FileInputStream(file);
                zipOut.putNextEntry(new ZipEntry(file.getName()));
                int len;
                while ((len = in.read(buf)) > 0) {
                    zipOut.write(buf, 0, len);
                }
                zipOut.closeEntry();
                in.close();
                file.delete();// 清除临时文档
            }
            zipOut.close();
        }
    }

    public static List<File> unZip(File srcFile, String destDirPath) throws RuntimeException {
        List<File> fileList = new ArrayList<>();
        long start = System.currentTimeMillis();
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            logger.error("解压缩失败，文件名[" + srcFile + "]不存在");
            return null;
        }
        // 开始解压
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(srcFile);
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                if (logger.isInfoEnabled()) {
                    logger.info("解压" + entry.getName());
                }
                // 如果是文件夹，就创建个文件夹
                if (entry.isDirectory()) {
                    String dirPath = destDirPath + "/" + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                } else {
                    // 如果是文件，就先创建一个文件，然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + "/" + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    InputStream is = zipFile.getInputStream(entry);
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[4096];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    fileList.add(targetFile);
                    // 关流顺序，先打开的后关闭
                    fos.flush();
                    fos.close();
                    is.close();
                }
            }
            long end = System.currentTimeMillis();
            if (logger.isDebugEnabled()) {
                logger.debug("解压完成，耗时：" + (end - start) + " ms");
            }
            return fileList;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                    return null;
                }
            }
        }
    }
}
